package com.parkinginfo.manager;


import com.google.android.maps.GeoPoint;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class GarageDetails {

    private static final int invalid_garage = 1;
    private static final int space_more = 2;
    private static final int space_medium = 3;
    private static final int space_low = 4;
    private static final int cost_low = 5;
    private static final int cost_medium = 6;
    private static final int cost_high = 7;

   //these are the keywords:

    // construct these once(ish), not 1000+ times...they are basically
    // #defines, and a baby step towards multiple language support.
    private static final String PRICE_STR       = "$%5.2f/hr";
    private static final String RESTRICTED_STR  = "Restricted";
    private static final String ESTIMATE_STR    = "Estimated %d of %d spaces available";
    private static final String INCREMENTAL_STR = "Incremental";

    private static final String BEGIN_TIME  = "BEG";
    private static final String END_TIME  = "END";
    private static final String RATE = "RATE";
    private static final String RQ_STRING   = "RQ";
    private static final String AM_STRING   = "AM";
    private static final String PM_STRING   = "PM";

    private static final String OPER_KEY  = "OPER";
    private static final String OCC_KEY   = "OCC";
    private static final String DESC_KEY  = "DESC";
    private static final String RATES_KEY = "RATES";
    private static final String TYPE_KEY  = "TYPE";
    private static final String RS_KEY    = "RS";
    private static final String RATE_KEY  = "RATE";
    private static final String LOCATION   = "LOC";
    private static final String NAME_KEY  = "NAME";


    public GeoPoint   nw;
    public GeoPoint   se;
    public GeoPoint   mid;
    public float      lat1,lon1,lat2,lon2;
    public String	  title;
    public String	  subtitle;
    public JSONObject TheGarageInformation;
    public String	  type;
    public String	  uniqueID;
    public Boolean    onStreet;
    public int        blockColor;
    public int        blockColorAvailability;
    public float      pricePerHour;
    public String     rateQualifier;
   
    public String     row,beg,end,from,to,rate,desc,rq,rr;

/*
 * you parse other details here.....
 */
    public boolean parseJSONData() throws JSONException 
    {
        if (TheGarageInformation == null) {
            return false;
        }

        //location parsing
        String loc = TheGarageInformation.getString(LOCATION);
        String[] params = loc.split(",");

        GeoPoint point1;
        GeoPoint point2;

        //lat/long larsing
        lon1 = Float.parseFloat(params[0]);
        lat1 = Float.parseFloat(params[1]);

        point1 = GoogleParkingActivity.getPoint(lat1,lon1);

        nw = point1;
        se = point1;
        mid = point1;

        onStreet = false;
        type = "garage";

        if (params.length == 4) {
            lon2 = Float.parseFloat(params[2]);
            lat2 = Float.parseFloat(params[3]);

            point2 = GoogleParkingActivity.getPoint(lat2,lon2);
            se = point2;
            mid = GoogleParkingActivity.getPoint((lat1 + lat2)/2,(lon1 + lon2)/2);

            onStreet = true;
            type = "blockface";
        }

        title = TheGarageInformation.getString(NAME_KEY);
        subtitle = null;

        beg			  = null;		// Indicates the begin/end time
        end			  = null;		// for this rate schedule (or
        rate		  = null;       // hours schedule use same var for
        rq			  = null;       // both)
        pricePerHour  = 0;
        rateQualifier = "";

        return true;
    }

    
    
    /*
     * Take help of these functions also.
     * I am not using these functions. These are from SFPark.org
     * Henry, you can get help from these functions...to parse more details about garage.
     * Use TheGarageInformation JSONObject to parse the garage details.
     * 
     */
    public String GarageInfoAvailibilityPrice(boolean shouldShowPrice) throws JSONException 
    {
        String descriptionOfAvailability = null;

        int numberOfOperationalSpaces;
        int numberOfOccupiedSpaces;
        rateQualifier = "";

        if (shouldShowPrice) {
 
            iconFinder(true); // side-effect (using it to set the pricePerHour for Garages...)
            if (pricePerHour == 0.00) {
                descriptionOfAvailability = rateQualifier;
            } else {
                descriptionOfAvailability = String.format(PRICE_STR, pricePerHour);
            }

            if(!onStreet) {
                if (pricePerHour > 0.0) {
                    descriptionOfAvailability = String.format(PRICE_STR, pricePerHour);
                }
            }
        } else {
            numberOfOperationalSpaces = TheGarageInformation.optInt(OPER_KEY,0);
            numberOfOccupiedSpaces = TheGarageInformation.optInt(OCC_KEY,0);
            if (numberOfOccupiedSpaces > numberOfOperationalSpaces) {
                descriptionOfAvailability = null;
            } else if (numberOfOperationalSpaces == 0 && numberOfOccupiedSpaces == 0) {
                descriptionOfAvailability = RESTRICTED_STR;
            } else {
                descriptionOfAvailability =
                        String.format(ESTIMATE_STR,
                                      (numberOfOperationalSpaces - numberOfOccupiedSpaces),
                                      numberOfOperationalSpaces);
            }
        }
        return descriptionOfAvailability;
    }

    public int iconFinder(boolean showPrice) throws JSONException {
        int itemImageName = 0;
        if (onStreet) {
            return itemImageName;
        }

        JSONObject rates = TheGarageInformation.optJSONObject(RATES_KEY);
        String type = TheGarageInformation.optString(TYPE_KEY);
        int used = TheGarageInformation.optInt(OCC_KEY,0);
        int capacity = TheGarageInformation.optInt(OPER_KEY,0);
        int avail = capacity - used;
        int availpercent = 0;

        boolean invalidData = true;

        if (capacity == 0) {
            availpercent = 0;
            invalidData = true;
        } else {
            availpercent = Math.round((((float)avail/(float)capacity) * 100) * 10)/10;
            invalidData = false;
        }

        int usedpercent = 100 - availpercent;

        if(avail < 2 && avail > 0 && availpercent != 0 && capacity <= 3){
            if(availpercent <= 15) {
                usedpercent = -57; // less than 15 percent available. hack
            } else {
                usedpercent = -58; // more than 15 percent available. hack
            }
        } else if(capacity == 0  && used == 0 && type == "ON") {
            // On street parking, force it to red as capacity is zero
            usedpercent = -42;
        }

        // since the code above and code below is adapted from
        // two different functions from webmap.js this
        // variable links amountUsed and usedpercent to keep
        // the source code consistent here in the java version
        // where the two functions are basically fused
        // together. This is a hack on a hack. *sigh*
        int amountUsed = usedpercent;
        if (invalidData) {
            itemImageName = invalid_garage;
        } else if (amountUsed > 85  || amountUsed == -42) {
            itemImageName = space_low;
        } else if ((amountUsed <= 85 && amountUsed >= 70) || amountUsed == -58) {
            itemImageName = space_medium;
        } else if ((amountUsed < 70 && amountUsed >=0) || amountUsed == -57) {
            itemImageName = space_more;
        }

        if((used > capacity) || amountUsed == -1 || amountUsed == -2) {
            itemImageName = invalid_garage;
        }

        if (showPrice) {
            if (rates != null) {
                JSONArray  rateArray = rates.optJSONArray(RS_KEY);
                if (!(rateArray == null)) {
                    boolean isDynamicPricing = true;
                    int rsc = rateArray.length();
                    for (int i =0; i < rsc; i++) {
                        JSONObject rateObject = rateArray.getJSONObject(i);
                        float phr = (float)rateObject.optDouble(RATE_KEY, 0);
                        String description = rateObject.optString(DESC_KEY);
                        if (description != null) {
                            if (description.contains(INCREMENTAL_STR)) {
                                itemImageName = nameFinder(phr);
                                isDynamicPricing = false;
                                pricePerHour = phr;
                                break;
                            }
                            else
                            {
                            	pricePerHour =4;
                            }
                        }
                    }
                }
            }
        }
        rateQualifier = rq;
        return itemImageName;
    }

    // Figure out which parking garage icon to display.
    public int nameFinder(float phr) {
        int imageName = -1;
        if (phr <= 2.00 && phr >= 0.00) {
            imageName = cost_low;
        } else if (phr > 2.00 && phr <= 4.00) {
            imageName = cost_medium;
        } else if (phr > 4.00) {
            imageName = cost_high;
        }
        return imageName;
    }

    // Update properties of start and end times for the current rate.
    public void rateStructureHandle(JSONObject rateObject) {
        // want null if fail not 'empty string' ?
        beg	 = rateObject.optString(BEGIN_TIME,  null);
        end	 = rateObject.optString(END_TIME,  null);
        rate = rateObject.optString(RATE, null);
        rq	 = rateObject.optString(RQ_STRING,	  null);
    }
}
